<?php

namespace App\Service;
use Illuminate\Support\Facades\Redis;

class RedisService
{   
    /**
     * 将key处存储的数字增加1
     * @param string $key
     * @return mixed
     */
    public static function incr($key)
    {
        return Redis::incr($key);
    }

    /**
     * @param string $key
     * @param float $increment
     * @return mixed | int
     */
    public static function incryBy($key, $increment)
    {
        return Redis::INCRBY($key, $increment);
    }

    /**
     * @param string $key
     * @param float $increment
     * @return mixed | float
     */
    public static function incrByFloat($key, $increment)
    {
        return Redis::incrByFloat($key, $increment);
    }

    /**
     * 添加指定的成员，并将给定的分数添加到存储在key中的已排序集
     *
     * @param $key
     * @param $score
     * @param $value
     */
    public static function zAdd($key, $score, $value)
    {
        Redis::zAdd($key, $score, $value);
    }

    /**
     * score 值在 min 和 max 之间的成员的数量
     *
     * @param $key
     * @param $score
     * @param $value
     */
    public static function zCount($key, $min, $max)
    {
        return Redis::zCount($key, $min, $max);
    }

    /**
     * 将一个成员的分数从一个给定的值中递增。
     * $key 或者 $member 不存在时，在递增时默认成员的原分数为0
     *
     * @param string $key 集合键值
     * @param float $value 分数值
     * @param mixed $member 成员
     */
    public static function zIncrBy($key, $value, $member)
    {
        Redis::zIncrBy($key, $value, $member);
    }

    /**
     * 返回指定排序集中的给定成员的秩，以最小的分数从0开始。zRevRank从0开始，以最大的分数开始
     *
     * @param string $key 集合键值
     * @param mixed $member 成员
     * @param mixed $value 成员的当前总分数值 [null]
     * @return string|boolean
     */
    public static function zRevRank($key, $member, $value = null)
    {
        $result = Redis::zRevRank($key, $member); // 返回指定成员的当前排名
        if (is_bool($result)) {
            self::zAdd($key, $value, $member);
            $result = Redis::zRevRank($key, $member);
        }
        $result += 1; // 因 排名最高从0开始，因为根据日常习惯 + 1
        return $result;
    }

    /**
     * 返回存储在指定键上的已排序集的元素，这些元素在范围[开始，结束]中有分数。在开始或结束前添加一个圆括号将其排除在范围之外。
     * 当开始和结束参数交换时，zRevRangeByScore以相反的顺序返回相同的项
     *
     * @param string $key 有序集合键值
     * @param int $start 开始下标
     * @param int $end 结束下标
     * @param boolean $withscore 是否显示分数
     * @return mixed 返回范围内的排行信息
     */
    public static function zRevRange($key, $start, $end, $withscore = null)
    {
        return Redis::zRevRange($key, $start, $end, $withscore);
    }

    /**
     * 返回集合中元素的数量.
     *
     * @param string $key 有序集合键值
     * @return mixed
     */
    public static function zCard($key)
    {
        return Redis::zCard($key);
    }

    /**
     * 返回有序集中，成员的分数值。
     *
     * @param $key
     * @param $member
     * @return mixed
     */
    public static function zScore($key, $member)
    {
        return Redis::zScore($key, $member);
    }

    /**
     * 获取key值
     *
     * @param string $key 键名称
     * @return string|boolean 返回键对应的值，无键值时返回false
     */
    public static function getKey($key)
    {
        if (Redis::exists($key)) {
            return Redis::get($key);
        }
        return false;
    }
    /**
     * 设置key值
     *
     * @param string $key 键名称
     * @param string|array|object $value 对应键的值
     */
    public static function setKey($key, $value)
    {
        Redis::set($key, $value); // 设置key值
    }

    /**
     * 设置key值
     *
     * @param string $key 键名称
     * @param string|array|object $value 对应键的值
     * @param integer $expireSeconds 过期时间（单位秒）
     */
    public static function setKeyWithExpire($key, $value, $expireSeconds)
    {
        Redis::set($key, $value); // 设置key值
        Redis::expire($key, $expireSeconds); // 设置key值过期时间
    }

    /**
     * 设置key值 过期时间
     *
     * @param string $key 键名称
     * @param integer $expireSeconds 过期时间（单位秒）
     */
    public static function setExpire($key, $expireSeconds)
    {
        Redis::expire($key, $expireSeconds); // 设置key值过期时间
    }

    /**
     * 删除指定的键值
     *
     * @param string|array $key 键名称
     */
    public static function delKey($key)
    {
        return Redis::del($key); //删除key
    }

    /**
     * 从key中获取一个值。如果哈希表不存在，或者key不存在，则返回FALSE。
     *
     * @param string $key
     * @param string $hashKey
     */
    public static function hGet($key, $hashKey)
    {
        return Redis::hGet($key, $hashKey);
    }

    /**
     * 向key中存储的散列添加值
     *
     * @paramv string $key
     * @param string $hashKey
     * @param mixed $value
     * @return mixed
     */
    public static function hSet($key, $hashKey, $value)
    {
        return Redis::hSet($key, $hashKey, $value);
    }

    /**
     *  填充整个哈希。非字符串值通过使用标准(字符串)转换为字符串。NULL值存储为空字符串
     * @param string $key
     * @param array $hashKeys
     * @return mixed
     */
    public static function hMset($key, $hashKeys)
    {
        return Redis::hMset($key, $hashKeys);
    }

    /**
     * 根据给定的数量增加散列字段的浮点值
     *
     * @param $key
     * @param $field
     * @param $increment
     */
    public static function hIncrByFloat($key, $field, $increment)
    {
        Redis::hIncrByFloat($key, $field, $increment);
    }

    /**
     * 将成员的值从散列中增加一个给定的值
     *
     * @param $key
     * @param $hashKey
     * @param $value
     */
    public static function hIncrBy($key, $hashKey, $value)
    {
        Redis::hIncrBy($key, $hashKey, $value);
    }

    /**
     * 验证指定的成员是否存在于key中。
     *
     * @param $key
     * @param $hashKey
     * @return boolean 如果成员存在于哈希表中，返回TRUE，否则返回FALSE
     */
    public static function hExists($key, $hashKey)
    {
        return Redis::hExists($key, $hashKey);
    }


    /**
     * 将一个或多个成员元素加入到集合中，已经存在于集合的成员元素将被忽略
     *
     * @param $key
     * @param $value1
     */
    public static function sAdd($key, $value1)
    {
        Redis::sAdd($key, $value1);
    }

    /**
     * 判断成员元素是否是集合的成员
     *
     * @param $key
     * @param $value
     */
    public static function sIsMember($key, $value)
    {
        return Redis::sIsMember($key, $value);
    }

    /**
     * 移除集合中的一个或多个成员元素，不存在的成员元素会被忽略
     *
     * @param $key
     * @param $member1
     */
    public static function sRem($key, $member1)
    {
        Redis::sRem($key, $member1);
    }

    /**
     * 返回集合中的所有的成员。 不存在的集合 key 被视为空集合
     *
     * @param string $key
     */
    public static function sMembers($key)
    {
        return Redis::sMembers($key);
    }

    /**
     * 返回键标识的列表的大小。
     * 如果列表不存在或为空，则命令返回0。如果密钥标识的数据类型不是列表，则命令返回FALSE。
     *
     * @param string $key 键名
     * @return mixed
     */
    public static function lLen($key)
    {
        return Redis::lLen($key);
    }

    /**
     * 返回存储在指定键(开始，结束)的列表中的指定元素。
     * start和stop被解释为索引:0第一个元素，第1个元素…-1最后一个元素，-2倒数第二
     *
     * @param $key
     * @param $start
     * @param $end
     * @return mixed
     */
    public static function lRange($key, $start, $end)
    {
        return Redis::lRange($key, $start, $end);
    }

    /**
     * 按照列表索引更改对应的值
     *
     * @param $key
     * @param $index
     * @param $value
     */
    public static function lSet($key, $index, $value)
    {
        Redis::lSet($key, $index, $value);
    }

    /**
     * 字符串值添加到列表的尾部(右)。如果键不存在，创建列表。如果键存在且不是列表，则返回FALSE。
     *
     * @param $key
     * @param $value
     */
    public static function rPush($key, $value)
    {
        Redis::rPush($key, $value);
    }

    /**
     * 字符串值添加到列表的头部(左)。如果键不存在，创建列表。如果键存在且不是列表，则返回FALSE。
     *
     * @param $key
     * @param $value
     */
    public static function lPush($key, $value)
    {
        Redis::lPush($key, $value);
    }

    /**
     * 将一个值插入到已存在的列表头部，列表不存在时操作无效。
     *
     * @param $key
     * @param $value
     */
    public static function lPushx($key, $value)
    {
        Redis::lPushx($key, $value);
    }

    /**
     * 返回并删除列表的最后一个元素。
     * @param string $key
     * @return mixed
     */
    public static function rPop($key)
    {
        return Redis::rPop($key);
    }

    /**
     *  通过索引获取列表中的元素。
     *  你也可以使用负数下标，以 -1 表示列表的最后一个元素， -2 表示列表的倒数第二个元素，以此类推。
     * @param string $key
     * @param integer $index
     * @return mixed
     */
    public static function lIndex($key, $index)
    {
        return Redis::lIndex($key, $index);
    }

    /**
     *  根据参数 COUNT 的值，移除列表中与参数 VALUE 相等的元素
     *  COUNT 的值可以是以下几种：
     *     count > 0 : 从表头开始向表尾搜索，移除与 VALUE 相等的元素，数量为 COUNT 。
     *     count < 0 : 从表尾开始向表头搜索，移除与 VALUE 相等的元素，数量为 COUNT 的绝对值。
     *     count = 0 : 移除表中所有与 VALUE 相等的值。
     * @param $key
     * @param $value
     * @param $count
     * @return mixed
     */
    public static function lRem($key, $value, $count)
    {
        return Redis::lRem($key, $value, $count);
    }

    /**
     * 以秒为单位返回 key 的剩余过期时间
     * @param string $key
     * @return mixed
     */
    public static function ttl($key)
    {
        return Redis::ttl($key);
    }

    /**
     * 判断是否存在该键值
     * @param string $key
     * @return bool 存在返回true，不存在返回false
     */
    public static function exists($key)
    {
        if (Redis::exists($key)) {
            return true;
        }
        return false;
    }

    /**
     * 从一个较大的字符串中返回一个比特
     * @param   string $key 键名
     * @param   int $offset 偏移量
     * @return  int     the bit value (0 or 1)
     */
    public static function getBit($key, $offset)
    {
        return Redis::getBit($key, $offset);
    }

    /**
     * 改变字符串的一个位
     * @param   string  $key
     * @param   int     $offset
     * @param   bool|int $value bool or int (1 or 0)
     * @return  int     0 or 1, the value of the bit before it was set.
     */
    public static function setBit($key, $offset, $value)
    {
        return Redis::setBit($key, $offset, $value);
    }

    /**
     * 批量初始化一个长度为7的有序集合
     * @param $key
     * @return array
     */
    public static function initWeekSet($key, $day1, $day2, $day3, $day4, $day5, $day6, $day7)
    {
        return Redis::multi()
            ->zAdd($key, 0, $day1)
            ->zAdd($key, 0, $day2)
            ->zAdd($key, 0, $day3)
            ->zAdd($key, 0, $day4)
            ->zAdd($key, 0, $day5)
            ->zAdd($key, 0, $day6)
            ->zAdd($key, 0, $day7)
            ->exec();
    }


    public static function sCard($key)
    {
        return Redis::sCard($key);
    }

    public static function geoAdd($key, $longitude, $latitude, $member)
    {
        return Redis::geoadd($key, $longitude, $latitude, $member);
    }

    /**
     * Returns the keys that match a certain pattern.
     *
     * @param   string  $pattern pattern, using '*' as a wildcard.
     * @return  array   of STRING: The keys that match a certain pattern.
     * @link    http://redis.io/commands/keys
     * @example
     * <pre>
     * $allKeys = $redis->keys('*');   // all keys will match this.
     * $keyWithUserPrefix = $redis->keys('user*');
     * </pre>
     */
    public static function keys($pattern)
    {
        return Redis::keys($pattern);
    }
}